package fr.inserm.umr915.libjson;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.w3c.dom.Document;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

public abstract class ArrayNode
	extends Node
	implements Iterable<Node>
	{
	private List<Node> list=null;
	static final String TAG="array";
	ArrayNode()
		{
		list=new ArrayList<Node>();
		}
	ArrayNode(int capacity)
		{
		list=new ArrayList<Node>(capacity);
		}
	public List<Node> getList()
		{
		return this.list;
		}
	
	@Override
	public NodeType getNodeType()
		{
		return NodeType.ARRAY;
		}
	
	public int size()
		{
		return getList().size();
		}
	
	public Node get(int i)
		{
		return getList().get(i);
		}
	
	@Override
	public Node clone(NodeFactory owner)
		{
		ArrayNode cp=owner.createArrayNode(size());
		for(int i=0;i<size();++i)
			{
			cp.getList().add(get(i).clone(owner));
			}
		return cp;
		}
	
	@Override
	public int hashCode() {
		return getList().hashCode();
		}
	
	
	@Override
	public void write(DataOutputStream out) throws IOException
		{
		out.writeByte((byte)getNodeType().ordinal());
		out.writeInt(size());
		for(Node n: getList())
			{
			n.write(out);
			}
		}
	
	@Override
	public void print(PrintWriter out)
		{
		out.print('[');
		for(int i=0;i< size();++i)
			{
			if(i>0) out.print(',');
			get(i).print(out);
			}
		out.print(']');
		}
	
	public int indexOf(Node node)
		{
		return getList().indexOf(node);
		}
	
	public boolean insert(String value)
		{
		return insert(getNodeFactory().createStringNode(value));
		}
	
	public boolean insert(Node node)
		{
		int i=indexOf(node);
		if(i!=-1) return false;
		add(node);
		return true;
		}
	
	public void add(Node node)
		{
		getList().add(node);
		}
	
	@Override
	public org.w3c.dom.Element asDom(Document owner)
		{
		org.w3c.dom.Element root= owner.createElement(TAG);
		for(int i=0;i< size();++i) root.appendChild(get(i).asDom(owner));
		return root;
		}
	@Override
	public void write(XMLStreamWriter out) throws XMLStreamException
		{
		out.writeStartElement(TAG);
		for(int i=0;i< size();++i) get(i).write(out);
		out.writeEndElement();
		}
	
	@Override
	public String toString()
		{
		return getList().toString();
		}
	
	@Override
	protected void saxHandler(ContentHandler handler) throws SAXException,
			IOException
		{
		AttributesImpl atts=new AttributesImpl();
		atts.addAttribute("", "", "size", "CDATA", String.valueOf(size()));
		handler.startElement("", "",TAG, atts);
		for(int i=0;i< size();++i) get(i).saxHandler(handler);
		handler.endElement("", "", TAG);
		}
	
	@Override
	public Iterator<Node> iterator()
		{
		return getList().iterator();
		}
	}
